<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from "vue"
import { getTaskInfoApi, startTaskApi, pauseTaskApi, stopTaskApi } from "@/api/task"
import { useRoute } from "vue-router"
import { TaskBaseInfo, TaskConfig } from "@/api/task/types/task"
import { cloneDeep } from "lodash-es"
import { TabTypeEnum, TASK_MODE, taskModeOptions, taskStatusOptions } from "@/constants/other-keys"
import { ElMessage } from "element-plus"
import TrainChart from "./train-chart.vue"
import EvalChart from "./eval-chart.vue"

let timer: number | null = null
const route = useRoute()
const taskId = ref<string>(route.query.id as string)
const TrainChartRef = ref()
const EvalChartRef = ref()
const percentage = ref<number>(0)
const DEFAULT_FORM_DATA: TaskBaseInfo = {
  task_id: undefined,
  task_name: "",
  task_process: 0,
  task_type: TabTypeEnum.STATIC,
  task_status: 0
}
const formData = ref<TaskBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const round = ref<number>(0)
const taskMode = ref<TASK_MODE>()
const taskModeMap = computed<{ [propName in TASK_MODE]: string }>(() => {
  return taskModeOptions.value.reduce(
    (acc, curr) => {
      acc[curr.value] = curr.name
      return acc
    },
    {} as { [propName in TASK_MODE]: string }
  )
})
const taskStatusMap = computed<{ [propName: string]: string }>(() => {
  return taskStatusOptions.value.reduce((acc: { [propName: string]: string }, curr) => {
    acc[curr.value] = curr.name
    return acc
  }, {})
})

const getTaskInfo = (id: string) => {
  getTaskInfoApi(id).then(({ data }) => {
    formData.value = {
      task_id: data.task_id,
      task_name: data.task_name,
      task_process: data.task_process,
      task_type: TabTypeEnum.STATIC,
      task_status: data.task_status
    }
    round.value = Number(JSON.parse(data.task_param).episode_config.max_episode)
    percentage.value = data.task_process as number
    if (data.task_status == 2) {
      percentage.value > 0 ? 100 : percentage.value
    }
    if (data.task_status == 3) {
      ElMessage.error("任务运行错误")
    }
    if (data.task_status == 4) {
      ElMessage.error("任务暂停")
    }
    taskMode.value = (JSON.parse(data.task_param).task_config as TaskConfig).mode
  })
}

const startLoading = ref(false)
const startTask = () => {
  startLoading.value = true
  startTaskApi(taskId.value as string).then(() => {
    ElMessage.success("任务已开始！")
    startLoading.value = false
    formData.value.task_status = 1
    formData.value.task_process = 0
  })
}
const pauseTask = () => {
  pauseTaskApi(taskId.value as string).then(() => {
    ElMessage.success("任务已暂停！")
    formData.value.task_status = 4
  })
}
const stopTask = () => {
  stopTaskApi(taskId.value as string).then(() => {
    ElMessage.success("任务已停止！")
    formData.value.task_status = 2
  })
}
const resize = () => {
  if (taskMode.value == "Train") TrainChartRef.value && TrainChartRef.value.resize()
  if (taskMode.value == "Inference") EvalChartRef.value && EvalChartRef.value.resize()
}

const statusText = computed(() => {
  if (formData.value.task_status == undefined) {
    return ""
  }
  return taskStatusMap.value[formData.value.task_status]
})
// 预期训练时长
const trainDuration = computed(() => {
  return round.value * 30
})

onMounted(() => {
  if (taskId.value != null) {
    getTaskInfo(taskId.value as string)
    timer = Number(
      setInterval(() => {
        if (formData.value.task_status == 1) {
          getTaskInfo(taskId.value as string)
        }
      }, 1000 * 60)
    )
  }
})

onBeforeUnmount(() => {
  timer && clearInterval(timer)
})

defineExpose({ resize })
</script>

<template>
  <div class="taskstatus-form">
    <div class="header mb-5">
      <el-text class="w-300px" truncated>任务名称：{{ formData.task_name }}</el-text>
      <el-text class="w-200px" truncated> 任务状态：{{ statusText }} </el-text>
      <el-text> 预期{{ taskModeMap[taskMode as TASK_MODE] }}时长：{{ trainDuration }} 秒 </el-text>
    </div>
    <el-card class="mb-6" body-class="control-toolbar">
      <el-tooltip class="box-item" effect="dark" content="开始">
        <el-button
          class="item"
          text
          size="large"
          :loading="startLoading"
          :disabled="formData.task_status == 1"
          @click="startTask"
        >
          <el-space>
            <SvgIcon name="video-start" class="success" />
          </el-space>
        </el-button>
      </el-tooltip>
      <div class="process">
        <div class="describe">进度：{{ formData.task_process }}%</div>
        <div class="progress">
          <el-progress
            :percentage="percentage == 0 && formData.task_status == 1 ? 100 : percentage"
            :stroke-width="18"
            :show-text="false"
            :status="percentage == 100 ? '' : 'warning'"
            :striped="percentage != 100"
            :striped-flow="percentage != 100"
            :duration="percentage == 100 ? 0 : 20"
            :color="percentage == 0 && formData.task_status == 1 ? 'rgba(64, 158, 255, 0.1)' : ''"
          />
        </div>
      </div>
      <el-tooltip class="box-item" effect="dark" content="暂停">
        <el-button class="item" text size="large" :disabled="formData.task_status != 1" @click="pauseTask">
          <el-space>
            <SvgIcon name="video-pause" class="primary" />
          </el-space>
        </el-button>
      </el-tooltip>
      <el-tooltip class="box-item" effect="dark" content="停止">
        <el-button class="item" text size="large" :disabled="formData.task_status != 1" @click="stopTask">
          <el-space>
            <SvgIcon name="video-stop" class="danger" />
          </el-space>
        </el-button>
      </el-tooltip>
    </el-card>
    <TrainChart v-if="taskMode == 'Train'" ref="TrainChartRef" :id="taskId" :task-status="formData.task_status" />
    <EvalChart
      v-if="taskMode == 'Inference'"
      ref="EvalChartRef"
      :id="taskId"
      :task-status="formData.task_status"
      :task-process="formData.task_process"
    />
  </div>
</template>
<style lang="scss" scoped>
.header {
  display: flex;
  align-items: center;
  // justify-content: space-between;
  flex-wrap: wrap;
  padding: 20px 0;
}
.taskstatus-form {
  margin: 0 auto;
  margin-top: 0;
}

@media screen and (max-width: 640px) {
  .taskstatus-form {
    width: 100%;
  }
}
@media screen and (min-width: 660px) {
  .taskstatus-form {
    width: 80%;
  }
}
@media screen and (min-width: 1200px) {
  .taskstatus-form {
    width: 70%;
  }
}

:deep(.control-toolbar) {
  display: flex;
  flex-direction: row;
  align-items: center;
  .el-button.is-disabled {
    .svg-icon {
      &.success {
        fill: rgba(148.6, 212.3, 117.1, 0.3);
      }
      &.primary {
        fill: rgb(121.3, 187.1, 255, 0.3);
      }
      &.danger {
        fill: rgb(248, 152.1, 152.1, 0.3);
      }
    }
  }
  .process {
    flex: 1;
    display: flex;
    align-items: center;
    padding: 0 10px;
    .describe {
      padding-right: 10px;
      font-size: 18px;
    }
    .progress {
      flex: 1;
    }
  }
  .item {
    height: 60px;
    padding: 10px;
  }
  .svg-icon {
    width: 2.5em;
    height: 2.5em;
    &.success {
      fill: rgb(148.6, 212.3, 117.1);
    }
    &.primary {
      fill: rgb(121.3, 187.1, 255);
    }
    &.danger {
      fill: rgb(248, 152.1, 152.1);
    }
  }
}
.el-button + .el-button {
  margin-left: 0;
}
</style>
